/*
 * @FileName: bsp_uart.c
 * @Author: GreyQiu qiushaogui@aikosolar.com
 * @Date: 2023-08-21 10:50:15
 * @LastEditors: GreyQiu qiushaogui@aikosolar.com
 * @LastEditTime: 2023-09-20 14:35:30
 * @Description: 
 * 
 * Copyright (c) 2023, All Rights Reserved. 
 */

#include "bsp_uart.h"

static uint8_t rx_buffer[WIFI_RX_LEN_MAX];

static uart_rx_complete_calllback rx_callback = NULL;

void uart1_dma_config(void)
{
    DMA_InitType DMA_InitStructure;

    RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_DMA); // 使能DMA时钟

    /* USARTy TX DMA1 Channel (triggered by USARTy Tx event) Config */
    DMA_Reset(WIFI_TX_DMA_Channel);
    DMA_InitStructure.PeriphAddr     = (uint32_t)(&(WIFI_USARTx->DAT));
    DMA_InitStructure.MemAddr        = (uint32_t)rx_buffer;
    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_DST;
    DMA_InitStructure.BufSize        = WIFI_TX_LEN_MAX;
    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_MODE_DISABLE;
    DMA_InitStructure.MemoryInc      = DMA_MEM_INC_MODE_ENABLE;
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_WIDTH_BYTE;
    DMA_InitStructure.MemDataSize    = DMA_MEM_DATA_WIDTH_BYTE;
    DMA_InitStructure.CircularMode   = DMA_CIRCULAR_MODE_DISABLE;
    DMA_InitStructure.Priority       = DMA_CH_PRIORITY_HIGH;
    DMA_InitStructure.Mem2Mem        = DMA_MEM2MEM_DISABLE;
    DMA_Initializes(WIFI_TX_DMA_Channel, &DMA_InitStructure);
    DMA_Channel_Request_Remap(WIFI_TX_DMA_Channel, DMA_REMAP_USART1_TX);

    /* USARTy RX DMA1 Channel (triggered by USARTy Rx event) Config */
    DMA_Reset(WIFI_RX_DMA_Channel);
    DMA_InitStructure.PeriphAddr = (uint32_t)(&(WIFI_USARTx->DAT));
    DMA_InitStructure.MemAddr    = (uint32_t)rx_buffer;
    DMA_InitStructure.Direction  = DMA_DIR_PERIPH_SRC;
    DMA_InitStructure.BufSize    = WIFI_RX_LEN_MAX;
    DMA_Initializes(WIFI_RX_DMA_Channel, &DMA_InitStructure);
    DMA_Channel_Request_Remap(WIFI_RX_DMA_Channel, DMA_REMAP_USART1_RX);
}

void uart1_interrupt_config(void)
{
    NVIC_InitType NVIC_InitStructure;

    /* Enable the USARTz Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel                   = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Initializes(&NVIC_InitStructure);
}

void uart1_interrupt_diable(void)
{
    NVIC_InitType NVIC_InitStructure;

    /* Enable the USARTz Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel                   = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;
    NVIC_Initializes(&NVIC_InitStructure);
}

void bsp_uart_init(void)
{
    USART_InitType USART_InitStructure;

    RCC_APB1_Peripheral_Clock_Enable(RCC_APB1_PERIPH_USART2); // 调试串口
    RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_USART1); // WIFI串口
    USART_Reset(WIFI_USARTx);

    USART_InitStructure.BaudRate            = BAUDRATE_WIFI;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.Mode                = USART_MODE_TX | USART_MODE_RX;
    DMA_Channel_Disable(WIFI_RX_DMA_Channel);
    DMA_Channel_Disable(WIFI_TX_DMA_Channel);
    USART_Interrput_Disable(WIFI_USARTx, USART_INT_IDLEF);

    uart1_interrupt_diable();

    uart1_dma_config();
    uart1_interrupt_config();
    /* init uart */
    USART_Initializes(WIFI_USARTx, &USART_InitStructure);

    /* Enable USARTyDMA Rx and TX request */
    USART_DMA_Transfer_Enable(WIFI_USARTx, USART_DMAREQ_RX | USART_DMAREQ_TX);
    // // /* Enable USARTy TX DMA Channel */
    // DMA_Channel_Enable(WIFI_TX_DMA_Channel);
    /* Enable USARTy RX DMA Channel */
    DMA_Channel_Enable(WIFI_RX_DMA_Channel);

    USART_Interrput_Enable(WIFI_USARTx, USART_INT_IDLEF);

    /* enable uart */
    USART_Enable(WIFI_USARTx);
}

void bsp_wifi_uart_send(uint8_t * buffer, uint32_t len)
{
//    if (DMA_Flag_Status_Get(DMA, DMA_CH4_TXCF) == SET)
    {
//        DMA_Flag_Status_Clear(DMA, DMA_CH4_TXCF);
        DMA_Channel_Disable(WIFI_TX_DMA_Channel);
        DMA_Memory_Address_Config(WIFI_TX_DMA_Channel, (uint32_t)buffer);
        DMA_Buffer_Size_Config(WIFI_TX_DMA_Channel, len);
        DMA_Channel_Enable(WIFI_TX_DMA_Channel);
    }

}

void bsp_wifi_uart_rx_reset(void)
{
    DMA_Channel_Disable(WIFI_RX_DMA_Channel);
    DMA_Current_Data_Transfer_Number_Set(WIFI_RX_DMA_Channel, WIFI_RX_LEN_MAX);
    DMA_Channel_Enable(WIFI_RX_DMA_Channel);

}

void bsp_wifi_uart_callback_register(uart_rx_complete_calllback cb)
{
    rx_callback = cb;
}


void USART1_IRQHandler(void)
{
    uint32_t len;
    if (USART_Flag_Status_Get(USART1, USART_FLAG_IDLEF) == SET)
    {
        if (rx_callback != NULL) {
            len = WIFI_RX_LEN_MAX - DMA_Current_Data_Transfer_Number_Get(WIFI_RX_DMA_Channel);
            rx_callback(rx_buffer, len);
        }
        bsp_wifi_uart_rx_reset();
        len = USART_Data_Receive(USART1);
        USART_Flag_Clear(USART1, USART_FLAG_IDLEF);
    }
}
